home *** CD-ROM | disk | FTP | other *** search
/ Aminet 34 / Aminet 34 (2000)(Schatztruhe)[!][Dec 1999].iso / Aminet / util / gnu / unixcmds.lha / unixcmds / src / od.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-06  |  7.5 KB  |  357 lines

  1. /* od - octal dump                 Author: Andy Tanenbaum */
  2.  
  3. #include <sys/types.h>
  4. #include <fcntl.h>
  5. #include <unistd.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8.  
  9.  
  10. int bflag, cflag, dflag, oflag, xflag, hflag, vflag;
  11. int linenr, width, state, ever;
  12. int prevwds[8];
  13. long off;
  14. char buf[512], buffer[BUFSIZ];
  15. int next;
  16. int bytespresent;
  17.  
  18. int main  (int argc, char **argv);
  19. long offset  (int argc, char *argv [], int k);
  20. void dumpfile  (void);
  21. void wdump  (short *words, int k, int radix);
  22. void bdump  (char odbytes [16 ], int k, int c);
  23. void odbyte  (int val, int c);
  24. int getwords  (short **words);
  25. int same  (short *w1, int *w2);
  26. void outword  (int val, int radix);
  27. void outnum  (int num, int radix);
  28. void addrout  (long l);
  29. char hexit  (int k);
  30. void usage  (void);
  31.  
  32. int main(argc, argv)
  33. /* [<][>][^][v][top][bottom][index][help] */
  34. int argc;
  35. char *argv[];
  36. {
  37.   int k, flags;
  38.   char *p;
  39.  
  40.   /* Process flags */
  41.   setbuf(stdout, buffer);
  42.   flags = 0;
  43.   p = argv[1];
  44.   if (argc > 1 && *p == '-') {
  45.         /* Flags present. */
  46.         flags++;
  47.         p++;
  48.         while (*p) {
  49.                 switch (*p) {
  50.                     case 'b':   bflag++;        break;
  51.                     case 'c':   cflag++;        break;
  52.                     case 'd':   dflag++;        break;
  53.                     case 'h':   hflag++;        break;
  54.                     case 'o':   oflag++;        break;
  55.                     case 'v':   vflag++;        break;  
  56.                     case 'x':   xflag++;        break;
  57.                     default:    usage();
  58.                 }
  59.                 p++;
  60.         }
  61.   } else {
  62.         oflag = 1;
  63.   }
  64.   if ((bflag | cflag | dflag | oflag | xflag) == 0) oflag = 1;
  65.   k = (flags ? 2 : 1);
  66.   if (bflag | cflag) {
  67.         width = 8;
  68.   } else if (oflag) {
  69.         width = 7;
  70.   } else if (dflag) {
  71.         width = 6;
  72.   } else {
  73.         width = 5;
  74.   }
  75.  
  76.   /* Process file name, if any. */
  77.   p = argv[k];
  78.   if (k < argc && *p != '+') {
  79.         /* Explicit file name given. */
  80.         close(0);
  81.         if (open(argv[k], O_RDONLY) != 0) {
  82.                 fprintf(stderr, "od: cannot open %s\n", argv[k]);
  83.                 exit(1);
  84.         }
  85.         k++;
  86.   }
  87.  
  88.   /* Process offset, if any. */
  89.   if (k < argc) {
  90.         /* Offset present. */
  91.         off = offset(argc, argv, k);
  92.         off = (off / 16L) * 16L;
  93.         lseek(0, off, SEEK_SET);
  94.   }
  95.   dumpfile();
  96.   addrout(off);
  97.   printf("\n");
  98.   return(0);
  99. }
  100.  
  101.  
  102. long offset(argc, argv, k)
  103. /* [<][>][^][v][top][bottom][index][help] */
  104. int argc;
  105. char *argv[];
  106. int k;
  107. {
  108.   int dot, radix;
  109.   char *p, c;
  110.   long val;
  111.  
  112.   /* See if the offset is decimal. */
  113.   dot = 0;
  114.   p = argv[k];
  115.   while (*p)
  116.         if (*p++ == '.') dot = 1;
  117.  
  118.   /* Convert offset to binary. */
  119.   radix = (dot ? 10 : 8);
  120.   val = 0;
  121.   p = argv[k];
  122.   if (*p == '+') p++;
  123.   while (*p != 0 && *p != '.') {
  124.         c = *p++;
  125.         if (c < '0' || c > '9') {
  126.                 printf("Bad character in offset: %c\n", c);
  127.                 exit(1);
  128.         }
  129.         val = radix * val + c - '0';
  130.   }
  131.  
  132.   p = argv[k + 1];
  133.   if (k + 1 == argc - 1 && *p == 'b') val = 512L * val;
  134.   return(val);
  135. }
  136.  
  137.  
  138. void dumpfile()
  139. /* [<][>][^][v][top][bottom][index][help] */
  140. {
  141.   int k;
  142.   short *words;
  143.  
  144.   while ((k = getwords(&words))) {      /* 'k' is # odbytes read */
  145.         if (!vflag) {           /* ensure 'lazy' evaluation */
  146.                 if (k == 16 && ever == 1 && same(words, prevwds)) {
  147.                         if (state == 0) {
  148.                                 printf("*\n");
  149.                                 state = 1;
  150.                                 off += 16;
  151.                                 continue;
  152.                         } else if (state == 1) {
  153.                                 off += 16;
  154.                                 continue;
  155.                         }
  156.                 }
  157.         }
  158.         addrout(off);
  159.         off += k;
  160.         state = 0;
  161.         ever = 1;
  162.         linenr = 1;
  163.         if (oflag) wdump(words, k, 8);
  164.         if (dflag) wdump(words, k, 10);
  165.         if (xflag) wdump(words, k, 16);
  166.         if (cflag) bdump((char *)words, k, (int)'c');
  167.         if (bflag) bdump((char *)words, k, (int)'b');
  168.         for (k = 0; k < 8; k++) prevwds[k] = words[k];
  169.         for (k = 0; k < 8; k++) words[k] = 0;
  170.   }
  171. }
  172.  
  173.  
  174. void wdump(words, k, radix)
  175. /* [<][>][^][v][top][bottom][index][help] */
  176. short *words;
  177. int k, radix;
  178. {
  179.   int i;
  180.  
  181.   if (linenr++ != 1) printf("       ");
  182.   for (i = 0; i < (k + 1) / 2; i++) outword(words[i], radix);
  183.   printf("\n");
  184. }
  185.  
  186.  
  187. void bdump(odbytes, k, c)
  188. /* [<][>][^][v][top][bottom][index][help] */
  189. char odbytes[16];
  190. int k;
  191. char c;
  192. {
  193.   int i;
  194.  
  195.   if (linenr++ != 1) printf("       ");
  196.   for (i = 0; i < k; i++) odbyte(odbytes[i] & 0377, c);
  197.   printf("\n");
  198. }
  199.  
  200. void odbyte(val, c)
  201. /* [<][>][^][v][top][bottom][index][help] */
  202. int val;
  203. char c;
  204. {
  205.   if (c == 'b') {
  206.         printf(" ");
  207.         outnum(val, 7);
  208.         return;
  209.   }
  210.   if (val == 0)
  211.         printf("  \\0");
  212.   else if (val == '\b')
  213.         printf("  \\b");
  214.   else if (val == '\f')
  215.         printf("  \\f");
  216.   else if (val == '\n')
  217.         printf("  \\n");
  218.   else if (val == '\r')
  219.         printf("  \\r");
  220.   else if (val == '\t')
  221.         printf("  \\t");
  222.   else if (val >= ' ' && val < 0177)
  223.         printf("   %c", val);
  224.   else {
  225.         printf(" ");
  226.         outnum(val, 7);
  227.   }
  228. }
  229.  
  230.  
  231. int getwords(words)
  232. /* [<][>][^][v][top][bottom][index][help] */
  233. short **words;
  234. {
  235.   int count;
  236.  
  237.   if (next >= bytespresent) {
  238.         bytespresent = read(0, buf, 512);
  239.         next = 0;
  240.   }
  241.   if (next >= bytespresent) return(0);
  242.   *words = (short *) &buf[next];
  243.   if (next + 16 <= bytespresent)
  244.         count = 16;
  245.   else
  246.         count = bytespresent - next;
  247.  
  248.   next += count;
  249.   return(count);
  250. }
  251.  
  252. int same(w1, w2)
  253. /* [<][>][^][v][top][bottom][index][help] */
  254. short *w1;
  255. int *w2;
  256. {
  257.   int i;
  258.   i = 8;
  259.   while (i--)
  260.         if (*w1++ != *w2++) return(0);
  261.   return(1);
  262. }
  263.  
  264. void outword(val, radix)
  265. /* [<][>][^][v][top][bottom][index][help] */
  266. int val, radix;
  267. {
  268. /* Output 'val' in 'radix' in a field of total size 'width'. */
  269.  
  270.   int i;
  271.  
  272.   if (radix == 16) i = width - 4;
  273.   if (radix == 10) i = width - 5;
  274.   if (radix == 8) i = width - 6;
  275.   if (i == 1)
  276.         printf(" ");
  277.   else if (i == 2)
  278.         printf("  ");
  279.   else if (i == 3)
  280.         printf("   ");
  281.   else if (i == 4)
  282.         printf("    ");
  283.   outnum(val, radix);
  284. }
  285.  
  286.  
  287. void outnum(num, radix)
  288. /* [<][>][^][v][top][bottom][index][help] */
  289. int num, radix;
  290. {
  291. /* Output a number with all leading 0s present.  Octal is 6 places,
  292.  * decimal is 5 places, hex is 4 places.
  293.  */
  294.   int d, i;
  295.   unsigned val;
  296.   char s[8];
  297.  
  298.   val = (unsigned) num;
  299.   if (radix == 8)
  300.         d = 6;
  301.   else if (radix == 10)
  302.         d = 5;
  303.   else if (radix == 16)
  304.         d = 4;
  305.   else if (radix == 7) {
  306.         d = 3;
  307.         radix = 8;
  308.   }
  309.   for (i = 0; i < d; i++) {
  310.         s[i] = val % radix;
  311.         val -= s[i];
  312.         val = val / radix;
  313.   }
  314.   for (i = d - 1; i >= 0; i--) {
  315.         if (s[i] > 9)
  316.                 printf("%c", 'a' + s[i] - 10);
  317.         else
  318.                 printf("%c", s[i] + '0');
  319.   }
  320. }
  321.  
  322.  
  323. void addrout(l)
  324. /* [<][>][^][v][top][bottom][index][help] */
  325. long l;
  326. {
  327.   int i;
  328.  
  329.   if (hflag == 0) {
  330.         for (i = 0; i < 7; i++)
  331.                 printf("%c", (int) ((l >> (18 - 3 * i)) & 07) + '0');
  332.   } else {
  333.         for (i = 0; i < 7; i++)
  334.                 printf("%c", hexit((int) ((l >> (24 - 4 * i)) & 0x0F)));
  335.   }
  336. }
  337.  
  338. char hexit(int k)
  339. /* [<][>][^][v][top][bottom][index][help] */
  340. {
  341.   char retchar;
  342.  
  343.   if (k <= 9)
  344.         retchar='0' + k;
  345.   else
  346.         retchar='A' + k - 10;
  347.  
  348.   return retchar;
  349. }
  350.  
  351. void usage()
  352. /* [<][>][^][v][top][bottom][index][help] */
  353. {
  354.   fprintf(stderr, "Usage: od [-bcdhovx] [file] [ [+] offset [.] [b] ]\n");
  355. }
  356. /* [<][>][^][v][top][bottom][index][help] */
  357.